﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Reflection;

namespace Atosenet.PluginEngine
{
    public abstract class PluginLoader : IDisposable
    {
        #region 成员



        #endregion


        #region 初始化

        public PluginLoader(string pluginDir, PluginType pType)
        {
            IncludeAllDirs = true;
            PluginDirectory = pluginDir;
            LoadType = pType;
            Plugins = new PluginCollection();

            IsInitialized = Initialize();
        }

        protected virtual bool Initialize()
        {
            return !String.IsNullOrEmpty(PluginDirectory) && Directory.Exists(PluginDirectory);
        }

        #endregion


        #region 公开函数

        public int Load()
        {
            if (!Directory.Exists(PluginDirectory))
                return -1;

            if (String.IsNullOrEmpty(PluginDirectory))
                return -2;

            return LoadPluginsFromDirectory(LoadType, PluginDirectory, IncludeAllDirs);
        }

        //public bool Load(string dir, string typeName)
        //{
 
        //}

        public virtual int LoadFrom(string dir, bool includeAllDirs)
        {
            return -1;
        }

        public void Dispose()
        {
            return;
        }

        #endregion


        #region 静态函数



        #endregion


        #region 核心函数

        protected virtual int LoadPluginsFromDirectory(PluginType type, string dir, bool includAllDirs)
        {
            string[] files = Directory.GetFiles(dir, "*.dll", includAllDirs ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
            int count = 0;

            foreach (string f in files)
            {
                count = LoadSinglePlugin(f, LoadType) ? count + 1 : count;
            }
            return count;
        }

        protected virtual bool LoadSinglePlugin(string fileName, PluginType pType)
        {
            try
            {
                Assembly asm = Assembly.LoadFile(fileName);

                if (asm == null)
                    return false;

                Type[] types = asm.GetTypes();

                foreach (Type t in types)
                {
                    if (t.IsAbstract)
                        continue;

                    object[] attrs = t.GetCustomAttributes(typeof(PluginAttribute), true);

                    if (attrs.Length > 0)
                    {
                        PluginAttribute pa = attrs[0] as PluginAttribute;

                        if (pa == null)
                            continue;

                        
                    }
                }

                return true;
            }
            catch
            {
                return false;
            }
        }

        #endregion


        #region 属性

        public string PluginDirectory
        {
            get;
            set;
        }

        public bool IncludeAllDirs
        {
            get;
            set;
        }

        public PluginType LoadType
        {
            get;
            set;
        }

        public bool IsInitialized
        {
            get;
            private set;
        }

        public PluginCollection Plugins
        {
            get;
            private set;
        }

        #endregion


        #region 事件



        #endregion


    }
}
